﻿namespace MicroCloud.Api.Message.Controllers
{
    #region "消息处理"
    /// <summary>
    /// 消息处理
    /// </summary>
    [Description("消息处理")]
    //[ModuleInfo(Code = "Message", Name = "消息处理", OrderNo = 1)]
    public class MsgController : MessageControllerBase
    {
        #region "属性"
        #region "获取 消息服务"
        /// <summary>
        /// 获取 消息服务
        /// </summary>
        protected IMessageService MessageService => ServiceProvider.GetService<IMessageService>();
        #endregion
        #region "获取 用户管理功能"
        /// <summary>
        /// 获取 用户管理功能
        /// </summary>
        protected UserManager<User> UserManager => ServiceProvider.GetService<UserManager<User>>();
        #endregion

        #endregion

        #region "Action方法"
        #region "获取消息"
        /// <summary>
        /// 获取消息
        /// </summary>
        /// <param name="request">分页请求</param>
        /// <returns>消息分页数据</returns>
        [HttpPost]
        [NonFunction]
        [Description("获取")]
        public virtual PageData<MessageDtoSimple> GetMessages(PageRequest request)
        {
            if (User?.Identity?.IsAuthenticated != true)
            {
                return new PageData<MessageDtoSimple>();
            }
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            var userId = User.Identity.GetUserId<long>();

            //分步查询，查询的筛选条件存在问题。
            //Expression<Func<MessageEntity, bool>> predicate = FilterService.GetExpression<MessageEntity>(request.FilterGroup);
            //var messageIds = MessageService.MessageReceivers.Where(o => o.ReceiverId == userId).Select(s => s.MessageId).ToList();
            //var messagesQueryable = MessageService.Messages.Where(o => messageIds.Contains(o.Id));
            //var page = CacheService.ToPageCache<MessageEntity, MessageDtoSimple>(MessageService.Messages, predicate, request.PageCondition, function);
            //return page.ToPageData();

            //联表查询-目前只能先从数据库全部加载后再做分页筛选处理
            #region "联表查询"
            request.AddDefaultSortCondition(new SortCondition("IsRead", ListSortDirection.Ascending), new SortCondition("SendTime", ListSortDirection.Descending));
            Expression<Func<MessageDtoSimple, bool>> predicate = FilterService.GetExpression<MessageDtoSimple>(request.FilterGroup);
            var messagesQueryable = (from T0 in MessageService.Messages
                                     join T1 in MessageService.MessageReceivers on new { MessageId = T0.Id, ReceiverId = userId } equals new { T1.MessageId, T1.ReceiverId }
                                     join T2 in UserManager.Users on T0.SenderId equals T2.Id
                                     select new MessageDtoSimple
                                     {
                                         Id = T0.Id,
                                         Method = T0.Method,
                                         Icon = T0.Icon,
                                         MessageType = T0.MessageType,
                                         MessageLevel = T0.MessageLevel,
                                         Title = T0.Title,
                                         Content = T0.Content,
                                         SendTime = T0.SendTime,
                                         IsSystem = T0.IsSystem,
                                         SenderId = T0.SenderId,
                                         SenderName = T2.UserName,
                                         SenderNickname = T2.NickName,
                                         LastReadTime = T1.LastReadTime,
                                         LastReadWay = T1.LastReadWay,
                                     }).ToList().AsQueryable();
            var messages = messagesQueryable.ToPageCache(predicate, request.PageCondition, m => m, function);
            return messages.ToPageData();
            #endregion
        }
        #endregion
        #region "获取未读"
        /// <summary>
        /// 获取未读
        /// </summary>
        /// <param name="request">分页请求</param>
        /// <returns>消息分页数据</returns>
        [HttpPost]
        [NonFunction]
        [Description("获取未读")]
        public virtual PageData<MessageDtoSimple> GetUnreadMessages(PageRequest request)
        {
            if (User?.Identity?.IsAuthenticated != true)
            {
                return new PageData<MessageDtoSimple>();
            }
            Check.NotNull(request, nameof(request));
            IFunction function = this.GetExecuteFunction();

            request.AddDefaultSortCondition(new SortCondition("SendTime", ListSortDirection.Descending));
            Expression<Func<MessageDtoSimple, bool>> predicate = FilterService.GetExpression<MessageDtoSimple>(request.FilterGroup);

            var userId = User.Identity.GetUserId<long>();
            //联表查询
            #region "联表查询"
            var messagesQueryable = (from T0 in MessageService.Messages
                                     join T1 in MessageService.MessageReceivers on new { MessageId = T0.Id, ReceiverId = userId } equals new { T1.MessageId, T1.ReceiverId }
                                     join T2 in UserManager.Users on T0.SenderId equals T2.Id
                                     where T1.LastReadTime == null
                                     select new MessageDtoSimple
                                     {
                                         Id = T0.Id,
                                         Method = T0.Method,
                                         Icon = T0.Icon,
                                         MessageType = T0.MessageType,
                                         MessageLevel = T0.MessageLevel,
                                         Title = T0.Title,
                                         Content = T0.Content,
                                         SendTime = T0.SendTime,
                                         IsSystem = T0.IsSystem,
                                         SenderId = T0.SenderId,
                                         SenderName = T2.UserName,
                                         SenderNickname = T2.NickName,
                                         LastReadTime = T1.LastReadTime,
                                         LastReadWay = T1.LastReadWay,
                                     }).ToList().AsQueryable();
            #endregion
            var messages = messagesQueryable.ToPageCache(predicate, request.PageCondition, m => m, function);

            return messages.ToPageData();
        }
        #endregion
        #region "获取详情"
        /// <summary>
        /// 获取详情
        /// </summary>
        /// <param name="dto">消息请求DTO</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [NonFunction]
        [UnitOfWork]
        [Description("获取详情")]
        public virtual async Task<AjaxResult> GetMessageDetails(MessageRequestDto dto)
        {
            if (User?.Identity?.IsAuthenticated != true)
            {
                return AjaxResult.Error(I18N.T("用户未登录"));
            }
            Check.NotNull(dto, nameof(dto));
            IFunction function = this.GetExecuteFunction();

            var userId = User.Identity.GetUserId<long>();
            var messageIds = dto.MessageIds;
            string key = messageIds.ToJsonString().ToMD5();
            var result = await CacheService.DistributedCache.GetAsync(key, async () => await MessageService.GetMessages(userId, messageIds), function);
            if (result.Succeeded)
            {
                var ids = result.Data.Select(o => o.Id).ToArray();
                var result2 = await MessageService.ReadMessages(dto.RequestWay, userId, true, ids);
                if (!result2.Succeeded)
                {
                    return result2.ToAjaxResult();
                }
            }
            return result.ToAjaxResult();
        }
        #endregion
        #region "阅读消息"
        /// <summary>
        /// 阅读消息
        /// </summary>
        /// <param name="dto">消息读取DTO</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [NonFunction]
        [UnitOfWork]
        [Description("阅读")]
        public virtual async Task<AjaxResult> ReadMessages(MessageReadDto dto)
        {
            if (User?.Identity?.IsAuthenticated != true)
            {
                return AjaxResult.Error(I18N.T("用户未登录"));
            }
            Check.NotNull(dto, nameof(dto));

            var userId = User.Identity.GetUserId<long>();
            var messageIds = dto.MessageIds;
            var result = await MessageService.ReadMessages(dto.RequestWay, userId, dto.Read, messageIds);
            return result.ToAjaxResult();
        }
        #endregion
        #region "删除消息"
        /// <summary>
        /// 删除消息
        /// </summary>
        /// <param name="messageIds">消息编号</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [NonFunction]
        [UnitOfWork]
        [Description("删除")]
        public virtual async Task<AjaxResult> DeleteMessages(params long[] messageIds)
        {
            if (User?.Identity?.IsAuthenticated != true)
            {
                return AjaxResult.Error(I18N.T("用户未登录"));
            }
            Check.NotNull(messageIds, nameof(messageIds));

            var userId = User.Identity.GetUserId<long>();
            var result = await MessageService.DeleteMessageReceiver(userId, messageIds);
            return result.ToAjaxResult();
        }
        #endregion

        #endregion

    }
    #endregion

}
